<template>
  <div class="dnssec-batch-page">
    <div class="content-wrapper">
          <!-- Modern Header Section -->
          <div class="header-section">
            <div class="header-content">
              <h1 class="main-title">DNSSEC 批量检测</h1>
              <p class="subtitle">批量验证递归服务器 检测权威侧的DNSSEC配置错误 的能力</p>
            </div>
            <div class="header-actions">
              <el-tooltip content="了解更多关于DNSSEC检测" placement="top">
                <el-button type="info" icon="InfoFilled" circle></el-button>
              </el-tooltip>
            </div>
          </div>

          <!-- Upload Section -->
          <div class="upload-container">
            <div class="upload-card" :class="{ 'has-file': selectedFile }">
              <div class="upload-area">
                <el-icon class="upload-icon" :class="{ 'success': selectedFile }">
                  <component :is="selectedFile ? 'CircleCheckFilled' : 'Upload'" />
                </el-icon>
                <h3 class="upload-title">{{ selectedFile ? selectedFile.name : '选择IP地址文件' }}</h3>
                <p class="upload-hint">
                  {{ selectedFile ? '文件已选择，可以开始检测' : '支持拖拽上传或点击选择文件' }}
                </p>
                <input 
                  type="file" 
                  ref="fileInput"
                  @change="handleFileSelect" 
                  accept=".txt"
                  class="file-input" 
                />
              </div>
              
              <div class="action-panel">
                <el-button
                  type="primary"
                  size="large"
                  :icon="selectedFile ? 'VideoPlay' : 'Upload'"
                  :loading="isScanning"
                  :disabled="!selectedFile"
                  @click="startDetection"
                  class="action-button primary-action"
                >
                  {{ detectStatus }}
                </el-button>

                <el-button
                  type="success"
                  size="large"
                  icon="Download"
                  :disabled="logEntries.length === 0"
                  @click="exportJSON"
                  class="action-button"
                >
                  导出结果
                </el-button>

                <el-button
                  type="info"
                  size="large"
                  icon="Upload"
                  @click="importResults"
                  class="action-button"
                >
                  导入结果
                </el-button>
              </div>
            </div>
          </div>

          <!-- Charts Section -->
          <transition name="fade">
            <div v-if="logEntries.length > 0" class="charts-section">
              <div class="charts-grid">
                <!-- 错误分布饼图 -->
                <div class="chart-card">
                  <div class="chart-header">
                    <h3 class="chart-title">DNSSEC验证错误分布</h3>
                    <el-tooltip content="查看错误类型分布情况" placement="top">
                      <el-icon><InfoFilled /></el-icon>
                    </el-tooltip>
                  </div>
                  <!-- 控制按钮 -->
                  <div class="data-switch">
                    <el-button
                      v-for="(type, index) in errorTypes"
                      :key="index"
                      @click="changeDataSource(index)"
                      :type="currentErrorTypeIndex === index ? 'primary' : 'default'"
                      size="small"
                      class="switch-btn"
                    >
                      {{ type }}
                    </el-button>
                  </div>
                  <div class="chart-container">
                    <v-chart :option="pieChartOption" class="piechart"/>
                  </div>
                </div>

                <!-- 统计概览条形图 -->
                <div class="chart-card">
                  <div class="chart-header">
                    <h3 class="chart-title">DNSSEC检测统计概览</h3>
                    <el-tooltip content="查看整体检测情况统计" placement="top">
                      <el-icon><InfoFilled /></el-icon>
                    </el-tooltip>
                  </div>
                  <div class="chart-container">
                    <v-chart :option="barChartOption" class="barchart"/>
                  </div>
                </div>
              </div>
            </div>
          </transition>
                <!-- Results Section -->
          <transition name="fade">
            <div v-if="logEntries.length > 0" class="results-section">
              <div class="section-header">
                <div class="header-left">
                  <h2 class="section-title">检测结果</h2>
                  <el-tag type="info" effect="plain" class="result-count">
                    {{ logEntries.length }} 条记录
                  </el-tag>
                </div>
                <div class="header-right">
                  <el-input
                    v-model="searchQuery"
                    placeholder="搜索IP地址..."
                    prefix-icon="Search"
                    clearable
                    class="search-input"
                  />
                </div>
              </div>

              <el-table
                :data="filteredResults"
                border
                stripe
                class="modern-table results-table"
                :max-height="500"
                highlight-current-row
              >
                <el-table-column prop="ip" label="IP地址" min-width="120" align="center"/>
                <el-table-column prop="time" label="检测时间" min-width="100" align="center"/>
                <el-table-column label="DNSSEC支持" min-width="100" align="center">
                  <template #default="{ row }">
                    <el-tag :type="getDnssecSupportStatus(row) ? 'success' : 'danger'" effect="dark">
                      {{ getDnssecSupportStatus(row) ? '支持' : '不支持' }}
                    </el-tag>
                  </template>
                </el-table-column>
                <el-table-column label="验证状态" min-width="100" align="center">
                  <template #default="{ row }">
                    <el-tag :type="row.status === 'safe' ? 'success' : 'danger'" effect="dark">
                      {{ row.status === 'safe' ? '验证成功' : '不支持验证' }}
                    </el-tag>
                  </template>
                </el-table-column>
                <el-table-column label="Unsupported DS" min-width="120" align="center">
                  <template #default="{ row }">
                    <el-tag :type="getErrorTypeTag(getErrorValue(row, 'unsupportedDs'))" effect="plain" size="small">
                      {{ getErrorStatusText(getErrorValue(row, 'unsupportedDs')) }}
                    </el-tag>
                  </template>
                </el-table-column>
                <el-table-column label="Unsupported DNSKEY" min-width="140" align="center">
                  <template #default="{ row }">
                    <el-tag :type="getErrorTypeTag(getErrorValue(row, 'unsupportedDnskey'))" effect="plain" size="small">
                      {{ getErrorStatusText(getErrorValue(row, 'unsupportedDnskey')) }}
                    </el-tag>
                  </template>
                </el-table-column>
                <el-table-column label="Signature Not Valid" min-width="140" align="center">
                  <template #default="{ row }">
                    <el-tag :type="getErrorTypeTag(getErrorValue(row, 'signatureNotValid'))" effect="plain" size="small">
                      {{ getErrorStatusText(getErrorValue(row, 'signatureNotValid')) }}
                    </el-tag>
                  </template>
                </el-table-column>
                <el-table-column label="Signature Expired" min-width="130" align="center">
                  <template #default="{ row }">
                    <el-tag :type="getErrorTypeTag(getErrorValue(row, 'signatureExpired'))" effect="plain" size="small">
                      {{ getErrorStatusText(getErrorValue(row, 'signatureExpired')) }}
                    </el-tag>
                  </template>
                </el-table-column>
                <el-table-column label="DNSKEY Missing" min-width="120" align="center">
                  <template #default="{ row }">
                    <el-tag :type="getErrorTypeTag(getErrorValue(row, 'dnskeyMissing'))" effect="plain" size="small">
                      {{ getErrorStatusText(getErrorValue(row, 'dnskeyMissing')) }}
                    </el-tag>
                  </template>
                </el-table-column>
                <el-table-column label="NSEC Missing" min-width="120" align="center">
                  <template #default="{ row }">
                    <el-tag :type="getErrorTypeTag(getErrorValue(row, 'nsecMissing'))" effect="plain" size="small">
                      {{ getErrorStatusText(getErrorValue(row, 'nsecMissing')) }}
                    </el-tag>
                  </template>
                </el-table-column>
                <el-table-column label="RRSIG Missing" min-width="120" align="center">
                  <template #default="{ row }">
                    <el-tag :type="getErrorTypeTag(getErrorValue(row, 'rrsigMissing'))" effect="plain" size="small">
                      {{ getErrorStatusText(getErrorValue(row, 'rrsigMissing')) }}
                    </el-tag>
                  </template>
                </el-table-column>
                <el-table-column label="No Zone Key" min-width="110" align="center">
                  <template #default="{ row }">
                    <el-tag :type="getErrorTypeTag(getErrorValue(row, 'noZoneKey'))" effect="plain" size="small">
                      {{ getErrorStatusText(getErrorValue(row, 'noZoneKey')) }}
                    </el-tag>
                  </template>
                </el-table-column>
              </el-table>
            </div>
          </transition>
    </div>
  </div>
</template>

<script setup>

import { ref, computed, onMounted, onBeforeUnmount, nextTick } from 'vue'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { PieChart, BarChart } from 'echarts/charts'
import axios from 'axios'
import { TitleComponent, TooltipComponent, LegendComponent } from 'echarts/components'
import { saveAs } from 'file-saver'
import VChart from 'vue-echarts'
import { ElMessage, ElNotification } from 'element-plus'
import { Upload, CircleCheckFilled, InfoFilled } from '@element-plus/icons-vue'


use([CanvasRenderer, PieChart, BarChart, TitleComponent, TooltipComponent, LegendComponent])

const COLOR_SCHEME = {
  safe: '#52c41a',    // 安全绿
  warning: '#faad14',  // 警告黄
  danger: '#ff4d4f',  // 危险红
  background: '#f0f9eb' // 背景浅绿
}

// 导航栏状态处理已移除，使用 Element Plus 布局

// 响应式数据
const ipRange = ref('')
const logEntries = ref([])
const isScanning = ref(false) // 加载状态
const selectedFile = ref(null)
const fileInput = ref(null)
const detectStatus = ref('开始探测')
const chartData = ref(null)
const currentErrorTypeIndex = ref(0)
const searchQuery = ref('')

const errorTypes = [
  'Unsupported DS',
  'Unsupported DNSKEY',
  'Signature Not Valid',
  'Signature Expired',
  'DNSKEY Missing',
  'NSEC Missing',
  'RRSIG Missing',
  'No Zone Key'
];

// 搜索过滤
const filteredResults = computed(() => {
  if (!searchQuery.value) return logEntries.value
  const query = searchQuery.value.toLowerCase()
  return logEntries.value.filter(item => 
    item.ip.toLowerCase().includes(query)
  )
})

// 统计数据计算
const statisticsData = computed(() => {
  const total = logEntries.value.length
  let dnssecSupportCount = 0
  let verifiedSuccessCount = 0

  logEntries.value.forEach(entry => {
    // 统计DNSSEC支持数量
    if (getDnssecSupportStatus(entry)) {
      dnssecSupportCount++
    }
    // 统计验证成功数量
    if (entry.status === 'safe') {
      verifiedSuccessCount++
    }
  })

  return {
    total,
    dnssecSupportCount,
    verifiedSuccessCount
  }
})

// 表格辅助函数
const getDnssecSupportStatus = (row) => {
  const supportInfo = row.message.basicInfo.find(item => item.label === 'DNSSEC支持')
  return supportInfo && supportInfo.value === '已支持'
}

const getResponseTime = (row) => {
  const timeInfo = row.message.basicInfo.find(item => item.label === '响应时间')
  return timeInfo ? timeInfo.value : '--'
}

const getErrorValue = (row, errorType) => {
  const errorInfo = row.message.errorDetails.find(item => item.label === errorType)
  return errorInfo ? errorInfo.value : 0
}

const getErrorStatusText = (value) => {
  switch(value) {
    case 0: return '未检测出错误'
    case 1: return '检测出错误'
    case 2: return '检测出正确的错误'
    case 3: return '丢包'
    default: return '未知'
  }
}

const getErrorTypeTag = (value) => {
  switch(value) {
    case 0: return 'danger'
    case 1: return 'warning'
    case 2: return 'success'
    case 3: return 'info'
    default: return 'info'
  }
}

const changeDataSource = (index) => {
  //currentErrorTypeIndex.value = index;
  if (!chartData.value) return; // 如果没有数据，直接返回

  const dataMap = {
    0: 'unsupportedDs',
    1: 'unsupportedDnskey',
    2: 'signatureNotValid',
    3: 'signatureExpired',
    4: 'dnskeyMissing',
    5: 'nsecMissing',
    6: 'rrsigMissing',
    7: 'noZoneKey'
  };

  // 使用存储的数据
  const currentData = chartData.value[dataMap[index]];
  
  // 更新饼图数据
  pieChartOption.value.series[0].data = [
    { name: '没有检测出错误', value: currentData[0] },
    { name: '检测出错误', value: currentData[1] },
    { name: '检测出正确的错误', value: currentData[2] },
    { name: '丢包', value: currentData[3] }
  ];
};
const pieChartOption = ref({
  series: [
    {
      //name: 'Unsupported DS',
      type: 'pie',
      radius: '70%',
      data: [],
      label: {
        formatter: '{b}: {d}%', // {b}=名称，{d}=百分比
        fontSize: 14
      }
    },
    {
      //name: 'Unsupported DNSKEY',
      type: 'pie',
      radius: '70%',
      data: [],
      label: {
        formatter: '{b}: {d}%', // {b}=名称，{d}=百分比
        fontSize: 14
      }
    },
    {
      //name: 'Signature Not Valid',
      type: 'pie',
      radius: '70%',
      data: [],
      label: {
        formatter: '{b}: {d}%', // {b}=名称，{d}=百分比
        fontSize: 14
      }
    },
    {
      //name: 'Signature Expired',
      type: 'pie',
      radius: '70%',
      data: [],
      label: {
        formatter: '{b}: {d}%', // {b}=名称，{d}=百分比
        fontSize: 14
      }
    },
    {
      //name: 'DNSKEY Missing',
      type: 'pie',
      radius: '70%',
      data: []
    },
    {
      //name: 'NSEC Missing',
      type: 'pie',
      radius: '70%',
      data: []
    },
    {
      //name: 'RRSIG Missing',
      type: 'pie',
      radius: '70%',
      data: []
    },
    {
      //name: 'No Zone Key',
      type: 'pie',
      radius: '70%',
      data: []
    }
  ],
  tooltip: {
    trigger: 'item',
    formatter: '{a} <br/>{b}: {c} ({d}%)'
  }
})

// 条形图配置
const barChartOption = computed(() => ({
  tooltip: {
    trigger: 'axis',
    formatter: (params) => {
      const data = params[0]
      const percentage = statisticsData.value.total > 0 
        ? ((data.value / statisticsData.value.total) * 100).toFixed(1) 
        : 0
      return `${data.name}: ${data.value} 条 (${percentage}%)`
    }
  },
  xAxis: {
    type: 'category',
    data: ['记录总数', 'DNSSEC支持', '验证成功'],
    axisLabel: {
      fontSize: 12,
      fontWeight: 'bold'
    }
  },
  yAxis: {
    type: 'value',
    axisLabel: {
      fontSize: 12
    }
  },
  series: [
    {
      name: '数量',
      type: 'bar',
      data: [
        {
          value: statisticsData.value.total,
          itemStyle: { color: '#409EFF' }
        },
        {
          value: statisticsData.value.dnssecSupportCount,
          itemStyle: { color: '#67C23A' }
        },
        {
          value: statisticsData.value.verifiedSuccessCount,
          itemStyle: { color: '#E6A23C' }
        }
      ],
      barWidth: '60%',
      label: {
        show: true,
        position: 'top',
        fontSize: 12,
        fontWeight: 'bold'
      }
    }
  ],
  grid: {
    left: '10%',
    right: '10%',
    bottom: '15%',
    top: '10%',
    containLabel: true
  }
}))

const API_ENDPOINT = 'http://8.163.29.103:9000/dnssec/batch'

// 从localStorage加载保存的数据
const loadSavedData = () => {
  const savedData = localStorage.getItem('dnssecDetectionData')
  if (savedData) {
    try {
      const parsedData = JSON.parse(savedData)
      // 检查数据是否过期（24小时）
      if (Date.now() - parsedData.timestamp > 24 * 60 * 60 * 1000) {
        clearSavedData()
        return null
      }
      return parsedData
    } catch (e) {
      console.error('加载保存的数据失败:', e)
      clearSavedData()
      return null
    }
  }
  return null
}

// 保存数据到localStorage
const saveData = () => {
  if (!selectedFile.value && !logEntries.value.length) return // 如果没有数据，不保存
  
  const dataToSave = {
    selectedFile: selectedFile.value ? { name: selectedFile.value.name } : null,
    logEntries: logEntries.value,
    chartData: chartData.value,
    currentErrorTypeIndex: currentErrorTypeIndex.value,
    pieChartOption: pieChartOption.value,
    detectStatus: detectStatus.value,
    isScanning: isScanning.value,
    timestamp: new Date().getTime()
  }
  localStorage.setItem('dnssecDetectionData', JSON.stringify(dataToSave))
}

// 清除保存的数据
const clearSavedData = () => {
  localStorage.removeItem('dnssecDetectionData')
}

// 文件选择处理
const handleFileSelect = (event) => {
  const file = event.target.files[0]
  if (!file) return

  if (!file.name.endsWith('.txt')) {
    ElMessage.error('请上传 .txt 格式的文件')
    return
  }

  // 自动重置之前的数据
  logEntries.value = []
  chartData.value = null
  currentErrorTypeIndex.value = 0
  detectStatus.value = '开始探测'
  isScanning.value = false
  
  // 重置图表
  pieChartOption.value.series[0].data = []

  selectedFile.value = file
  ElMessage.success('文件选择成功，请点击开始探测')
  saveData() // 保存新的文件选择状态
}

// 开始探测
const startDetection = async () => {
  if (!selectedFile.value || isScanning.value) return

  isScanning.value = true
  detectStatus.value = '探测中...'
  logEntries.value = [] // 清空之前的日志
  saveData() // 保存探测状态

  try {
    const formData = new FormData()
    formData.append('file', selectedFile.value)

    const response = await axios.post(
      API_ENDPOINT,
      formData,
      {
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      }
    )

    if (response.data.code === 200) {
      console.log('API Response:', response.data)
      if (!Array.isArray(response.data.data)) {
        console.error('API response data is not an array:', response.data.data)
        ElMessage.error('返回数据格式错误')
        return
      }
      
      // 确保数据中包含必要的字段
      const validData = response.data.data.filter(item => {
        const isValid = item && typeof item === 'object' && 'ip' in item
        if (!isValid) {
          console.warn('Invalid data item:', item)
        }
        return isValid
      })

      if (validData.length === 0) {
        console.error('No valid data items found')
        ElMessage.error('没有有效的探测数据')
        return
      }

      updateScanResults(validData, Date.now() - Date.now())
      const summary = summarizeScanResults(validData)
      updateCharts(summary)
      detectStatus.value = '探测完成'
      ElMessage.success('探测完成')
      saveData() // 探测完成后保存数据
    } else {
      detectStatus.value = '探测失败'
      ElMessage.error(response.data.message || '探测失败')
      saveData() // 出错后也保存状态
    }
  } catch (error) {
    console.error('探测出错:', error)
    detectStatus.value = '探测失败'
    ElMessage.error('探测过程中发生错误')
    saveData() // 出错后也保存状态
  } finally {
    isScanning.value = false
    saveData() // 确保状态被保存
  }
}

// 重置数据
const resetData = () => {
  logEntries.value = []
  chartData.value = null
  currentErrorTypeIndex.value = 0
  selectedFile.value = null
  detectStatus.value = '开始探测'
  isScanning.value = false
  if (fileInput.value) {
    fileInput.value.value = '' // 清空文件输入
  }
  clearSavedData()
  
  // 重置图表
  pieChartOption.value.series[0].data = []
}

// 组件挂载时加载保存的数据
onMounted(() => {
  const savedData = loadSavedData()
  if (savedData) {
    selectedFile.value = savedData.selectedFile ? new File([], savedData.selectedFile.name, { type: 'text/plain' }) : null
    logEntries.value = savedData.logEntries || []
    chartData.value = savedData.chartData || null
    currentErrorTypeIndex.value = savedData.currentErrorTypeIndex || 0
    pieChartOption.value = savedData.pieChartOption || pieChartOption.value
    detectStatus.value = savedData.detectStatus || '开始探测'
    isScanning.value = savedData.isScanning || false

    nextTick(() => {
      if (chartData.value) {
        changeDataSource(currentErrorTypeIndex.value)
      }
    })
  }
})

// 组件卸载前保存数据
onBeforeUnmount(() => {
  if (logEntries.value.length > 0) {
    saveData()
  }
})

// 结果统计
const summarizeScanResults = (dataArray) => {
  const stats = {}

  const fieldsToCount = [
    'unsupportedDs',
    'unsupportedDnskey',
    'signatureNotValid',
    'signatureExpired',
    'dnskeyMissing',
    'nsecMissing',
    'rrsigMissing',
    'noZoneKey'
  ]

  fieldsToCount.forEach(field => {
    stats[field] = [0, 0, 0, 0] // 初始化 0~3 四个等级
  })

  dataArray.forEach(result => {
    fieldsToCount.forEach(field => {
      const value = result[field]
      if (value >= 0 && value <= 3) {
        stats[field][value] += 1
      }
    })
  })

  return stats
}

// 更新日志内容
const updateScanResults = (resultArray, responseTime) => {
  console.log('Processing results:', resultArray); // 添加日志
  resultArray.forEach(resultData => {
    console.log('Processing single result:', resultData); // 添加日志
    const formattedData = formatDNSSECResult(resultData, responseTime)
    logEntries.value.unshift({
      time: new Date().toLocaleTimeString(),
      ip: resultData.ip || '未知IP',
      message: formattedData,
      status: resultData.is_dnssec_verified ? 'safe' : 'danger'
    })
  })
}

// 数据结构转换器
const formatDNSSECResult = (data, responseTime) => {
  console.log('Formatting data:', data); // 添加日志
  return {
    basicInfo: [
      { label: 'DNSSEC支持', value: data.is_dnssec_support ? '已支持' : '未支持', type: 'status' },
      { label: '验证状态', value: data.is_dnssec_verified ? '验证成功' : '不支持验证', type: 'status' },
      { label: '响应时间', value: `${responseTime}ms`, type: 'info' }
    ],
    errorDetails: [
      { label: 'unsupportedDs', value: data.unsupportedDs, type: 'error' },
      { label: 'unsupportedDnskey', value: data.unsupportedDnskey, type: 'error' },
      { label: 'signatureNotValid', value: data.signatureNotValid, type: 'error' },
      { label: 'signatureExpired', value: data.signatureExpired, type: 'error' },
      { label: 'dnskeyMissing', value: data.dnskeyMissing, type: 'error' },
      { label: 'nsecMissing', value: data.nsecMissing, type: 'error' },
      { label: 'rrsigMissing', value: data.rrsigMissing, type: 'error' },
      { label: 'noZoneKey', value: data.noZoneKey, type: 'error' }
    ]
  }
}

const keys = [
  'unsupportedDs',
  'unsupportedDnskey',
  'signatureNotValid',
  'signatureExpired',
  'dnskeyMissing',
  'nsecMissing',
  'rrsigMissing',
  'noZoneKey'
];

// 更新图表数据
const updateCharts = (data) => {
  console.log('Incoming data:', data);
  chartData.value = data;
  changeDataSource(0);
}

// 错误处理
const handleError = (error) => {
  console.error('请求失败:', error)
  logEntries.value.push({
    time: new Date().toLocaleTimeString(),
    message: `探测失败: ${error.message}`,
    status: 'danger'
  })
}

// 导出JSON结果
const exportJSON = () => {
  if (logEntries.value.length === 0) {
    ElMessage.warning('没有数据可导出')
    return
  }

  const exportData = {
    exportTime: new Date().toISOString(),
    type: 'dnssec_batch_results',
    totalCount: logEntries.value.length,
    chartData: chartData.value,
    results: logEntries.value
  }

  const blob = new Blob([JSON.stringify(exportData, null, 2)], { 
    type: 'application/json;charset=utf-8' 
  })
  saveAs(blob, `dnssec_results_${Date.now()}.json`)
  ElMessage.success('导出成功')
}

// 导入JSON结果功能
const importResults = async () => {
  const input = document.createElement('input')
  input.type = 'file'
  input.accept = '.json'
  input.onchange = (event) => {
    const file = event.target.files[0]
    if (!file) return

    const reader = new FileReader()
    reader.onload = async (e) => {
      try {
        const importedData = JSON.parse(e.target.result)
        
        // 验证数据格式
        if (!importedData.results || !Array.isArray(importedData.results)) {
          ElMessage.error('文件格式不正确，请选择有效的DNSSEC检测结果JSON文件')
          return
        }

        // 清除现有数据
        logEntries.value = []
        chartData.value = null
        currentErrorTypeIndex.value = 0
        
        // 导入数据
        logEntries.value = importedData.results
        chartData.value = importedData.chartData || null

        // 如果没有图表数据，重新计算
        if (!chartData.value && logEntries.value.length > 0) {
          // 从日志数据重新构建原始数据用于统计
          const reconstructedData = logEntries.value.map(entry => {
            const result = { ip: entry.ip }
            entry.message.errorDetails.forEach(error => {
              result[error.label] = error.value
            })
            return result
          })
          chartData.value = summarizeScanResults(reconstructedData)
        }

        // 更新状态
        detectStatus.value = logEntries.value.length > 0 ? '已导入数据' : '开始探测'
        selectedFile.value = { name: '导入的JSON文件' }

        // 等待DOM更新后再渲染图表
        await nextTick()
        setTimeout(() => {
          if (chartData.value) {
            changeDataSource(0)
          }
        }, 100)

        // 保存到localStorage
        saveData()

        ElMessage.success(`成功导入 ${logEntries.value.length} 条记录`)

      } catch (error) {
        console.error('导入失败:', error)
        ElMessage.error('文件解析错误，请检查文件格式')
      }
    }
    reader.readAsText(file)
  }
  input.click()
}

const clearLogs = () => {
  logEntries.value = []  // 清空日志数组
}

</script>

<style scoped>
.page-container {
  height: 100vh;
  background: #f8fafc;
}

.nav-aside {
  position: fixed;
  height: 100vh;
  background-color: transparent;
  z-index: 1000;
  width: 240px !important;
}

.main-container {
  min-height: 100vh;
  margin-left: 240px;
}

.main-content {
  padding: 0;
  overflow-x: hidden;
}

.content-wrapper {
  padding: 2rem;
  height: 100%;
  box-sizing: border-box;
}
/* Modern Header Styles */
.header-section {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 2rem;
  background: linear-gradient(135deg, #1a237e 0%, #0d47a1 100%);
  border-radius: 16px;
  padding: 2rem;
  color: white;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
}

.header-content {
  flex: 1;
}

.main-title {
  font-size: 2rem;
  font-weight: 600;
  margin: 0;
  line-height: 1.2;
  color: white;
}

.subtitle {
  font-size: 1.1rem;
  opacity: 0.9;
  margin: 0.5rem 0 0;
  color: rgba(255, 255, 255, 0.9);
}

.header-actions {
  display: flex;
  align-items: center;
}

.tooltip-wrapper {
  position: relative;
  display: inline-block;
}

.info-btn {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.3);
  background: rgba(255, 255, 255, 0.1);
  color: white;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.3s ease;
  backdrop-filter: blur(10px);
}

.info-btn:hover {
  background: rgba(255, 255, 255, 0.2);
  border-color: rgba(255, 255, 255, 0.5);
  transform: scale(1.05);
}

.info-icon {
  font-size: 1.2rem;
}

/* Upload Section */
.upload-container {
  margin-bottom: 2rem;
}

.upload-card {
  background: white;
  border-radius: 16px;
  padding: 2rem;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
  transition: all 0.3s ease;
}

.upload-card.has-file .upload-area {
  border-color: var(--el-color-success);
  background: var(--el-color-success-light-9);
}

.upload-area {
  border: 2px dashed #e2e8f0;
  border-radius: 12px;
  padding: 3rem 2rem;
  text-align: center;
  transition: all 0.3s ease;
  cursor: pointer;
  position: relative;
  margin-bottom: 1.5rem;
}

.upload-area:hover {
  border-color: var(--el-color-primary);
  background: var(--el-color-primary-light-9);
}

.upload-icon {
  font-size: 3rem;
  color: var(--el-color-primary);
  margin-bottom: 1rem;
  transition: all 0.3s ease;
}

.upload-icon.success {
  color: var(--el-color-success);
  animation: checkSuccess 0.5s ease;
}

@keyframes checkSuccess {
  0% { transform: scale(1); }
  50% { transform: scale(1.2); }
  100% { transform: scale(1); }
}

.upload-title {
  font-size: 1.25rem;
  color: var(--el-text-color-primary);
  margin: 0 0 0.5rem;
}

.upload-hint {
  color: var(--el-text-color-secondary);
  margin: 0;
}

.file-input {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}

.action-panel {
  display: flex;
  gap: 1rem;
  justify-content: center;
}

.action-button {
  min-width: 120px;
  transition: all 0.3s ease;
}

.primary-action {
  transform: scale(1);
}

.primary-action:hover {
  transform: scale(1.02);
}

/* Charts Section */
.charts-section {
  margin-bottom: 2rem;
  animation: fadeIn 0.3s ease;
}

.chart-card {
  background: white;
  border-radius: 16px;
  padding: 1.5rem;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
}

.chart-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1rem;
}

.chart-title {
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--el-text-color-primary);
  margin: 0;
}

.data-switch {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

.switch-btn {
  font-size: 0.75rem;
}

.chart-container {
  height: 400px;
}

.piechart,
.barchart {
  width: 100%;
  height: 100%;
}

/* Charts Grid Layout */
.charts-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2rem;
  margin-bottom: 2rem;
}

/* Results Section */
.results-section {
  background: white;
  border-radius: 16px;
  padding: 1.5rem;
  margin-bottom: 2rem;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
  animation: fadeIn 0.3s ease;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1.5rem;
  flex-wrap: wrap;
  gap: 1rem;
}

.header-left {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.section-title {
  font-size: 1.5rem;
  font-weight: 600;
  color: var(--el-text-color-primary);
  margin: 0;
}

.result-count {
  font-size: 0.875rem;
}

/* Animations */
@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s ease, transform 0.3s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
  transform: translateY(10px);
}
/* Log card styles */
.log-container {
  max-height: 500px;
  overflow-y: auto;
}

.log-card {
  padding: 16px;
  border-left: 4px solid transparent;
  transition: all 0.3s ease;
  background: white;
  margin-bottom: 1rem;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

.log-card.danger {
  border-color: #ff4d4f;
  background: linear-gradient(to right, rgba(255,76,76,0.05) 0%, rgba(255,76,76,0.01) 100%);
}

.log-card.safe {
  border-color: #52c41a;
  background: linear-gradient(to right, rgba(82,196,26,0.05) 0%, rgba(82,196,26,0.01) 100%);
}

.log-meta {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
}

.status-indicator {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  margin-right: 12px;
}

.status-indicator.safe {
  background: #52c41a;
}

.status-indicator.danger {
  background: #ff4d4f;
}

.log-time {
  color: #666;
  font-family: 'Courier New', monospace;
  font-size: 0.9em;
}

.ip-badge {
  margin-left: auto;
  background: #f0f2f5;
  color: #606266;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 0.85em;
}

.log-details {
  padding-left: 28px;
}

.info-block {
  border-bottom: 1px solid #eee;
  padding-bottom: 12px;
  margin-bottom: 12px;
}

.detail-item {
  color: #606266;
  margin: 6px 0;
  display: flex;
  align-items: center;
}

.info-label {
  color: #595959;
  font-weight: 500;
  margin-right: 8px;
}

.info-value.success {
  color: #52c41a;
  font-weight: 600;
}

.info-value.danger {
  color: #ff4d4f;
  font-weight: 600;
}

.error-title {
  font-size: 1rem;
  color: #303133;
  margin: 1rem 0 0.5rem;
  display: flex;
  align-items: center;
}

.title-icon {
  margin-right: 8px;
}

.error-block {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}

.error-item {
  background: #fff3f5;
  padding: 8px;
  border-radius: 4px;
  display: flex;
  align-items: center;
  transition: all 0.3s ease;
}

.error-item:hover {
  background: rgba(0,0,0,0.03);
  transform: translateX(4px);
}

.error-label {
  color: #595959;
  font-weight: 500;
  margin-right: 6px;
}

.status-safe {
  color: #52c41a;
  font-weight: 500;
}

.status-danger {
  color: #ff4d4f;
  font-weight: 600;
}

.status-warning {
  color: #faad14;
  font-weight: 500;
}

/* Responsive Design */
@media screen and (max-width: 1024px) {
  .main-container {
    margin-left: 0;
  }
  
  .nav-aside {
    transform: translateX(-100%);
    transition: transform 0.3s ease;
  }
}

@media screen and (max-width: 768px) {
  .content-wrapper {
    padding: 1rem;
  }

  .header-section {
    padding: 1.5rem;
  }

  .main-title {
    font-size: 1.5rem;
  }

  .action-panel {
    flex-direction: column;
  }

  .action-button {
    width: 100%;
  }

  .error-block {
    grid-template-columns: 1fr;
  }

  .data-switch {
    justify-content: flex-start;
  }

  .switch-btn {
    flex: 1 1 calc(50% - 0.25rem);
    min-width: 120px;
  }

  .charts-grid {
    grid-template-columns: 1fr;
    gap: 1rem;
  }
}

/* Table Styles */
.results-section {
  background: white;
  border-radius: 16px;
  padding: 1.5rem;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
  margin-bottom: 2rem;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1.5rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid #f0f0f0;
}

.header-left {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.section-title {
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--el-text-color-primary);
  margin: 0;
}

.result-count {
  font-size: 0.875rem;
}

.header-right {
  display: flex;
  align-items: center;
}

.search-input {
  width: 280px;
}

.modern-table {
  border-radius: 8px;
  overflow: hidden;
  border: 1px solid var(--el-border-color-light);
}

.modern-table :deep(.el-table__header) {
  background: var(--el-color-primary-light-9);
}

.modern-table :deep(.el-table__header th) {
  background: var(--el-color-primary-light-9) !important;
  color: var(--el-text-color-primary);
  font-weight: 600;
  border-bottom: 1px solid var(--el-border-color);
}

.modern-table :deep(.el-table__body tr:hover > td) {
  background: var(--el-color-primary-light-9) !important;
}

.modern-table :deep(.el-table__row--striped td) {
  background: var(--el-color-info-light-9);
}

.modern-table :deep(.el-table__row--striped:hover td) {
  background: var(--el-color-primary-light-9) !important;
}

.truncate-text {
  max-width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  display: inline-block;
}

@media screen and (max-width: 768px) {
  .section-header {
    flex-direction: column;
    gap: 1rem;
    align-items: stretch;
  }
  
  .search-input {
    width: 100%;
  }
  
  .modern-table {
    font-size: 12px;
  }
  
  .modern-table :deep(.el-table th),
  .modern-table :deep(.el-table td) {
    padding: 8px 4px;
  }
}
</style>

